/**
 * Configuration
 * -------------------------------------------------
 * 
 * This class will creates configurations with automata.
 * 
 * @author abrao
 */
package model.constraints.inherited;


import model.constraints.AbstractConstraint;
import automata.Fsa;
import automata.State;
import automata.StateSet;

public abstract class Configuration implements Comparable<Configuration> {
	
	protected State s;
	protected Fsa f;
	protected AbstractConstraint constraint;

	public Configuration(State s, Fsa f, AbstractConstraint k) {
		this.s = s;
		this.f = f;
		this.constraint = k;
	}

	public Configuration() {}
		
	public State getState() {
		return s;
	}

	public Fsa getFsa() {
		return f;
	}

	public AbstractConstraint getConstraint() {
		return constraint;
	}	
	

	/**
	 * Checks that arrived at the end of automaton Source 
	 * @return true or false 
	 */
	public boolean isSourceEnd(){		
		Fsa fsa = getFsa();
		State state = getState();
		StateSet stateSet = fsa.get_final_states();
		AbstractConstraint constraint = getConstraint();
		
		int fposition = constraint.getFsaPosition(fsa);
		
		if ((fposition == 2) && (stateSet.contains(state)))
			return true;
		
		return false;
	}
	
	/**
	 * Checks that arrived at the end of automaton Target 
	 * @return true or false 
	 */
	public boolean isTargetEnd(){
		Fsa fsa = getFsa();
		State state = getState();
		StateSet stateSet = fsa.get_final_states();
		AbstractConstraint constraint = getConstraint();
		
		int fposition = constraint.getFsaPosition(fsa);
		
		if ((fposition == 3) && (stateSet.contains(state)))
			return true;
		
		return false;
	}
	

	public int getPosition(){
		return constraint.getJ(s.elt);
	}
	
	public String getEquality(){
		return constraint.getEquality(f, s);
	}
	
	/**
	* This rule defines which follow from the verification of the final state and current state
	* @param Configuration c (object)
	* @return int
	*/
	public int roleType() {
		
		Fsa f = this.getFsa();
		State sf =  this.getState();
		StateSet setF = f.get_final_states();
		AbstractConstraint k = (AbstractConstraint)  this.getConstraint();
		int fposition = k.getFsaPosition(f);
		
		if (fposition == 3){ //T" - right side
			if (setF.contains(sf))
				return 1; 
			else
				return 3;
		}
		
		if (fposition == 2){ //T' - left side	
			if (setF.contains(sf))
				return 2;
			else
				return 4;
		}
		
		if (fposition == 1){ //M - context
			if (setF.contains(sf))
				return 5;
			else
				return 6;
		}		
		
		if (fposition == 4){ //Tc - condition	
			if (setF.contains(sf))
				return 7;
			else
				return 8;
		}
		
		return 0;
	}
		
	
	/**
	 * This function will sort the automata (context, left, right)
	 * - this class should implements "Comparable"
	 * @param Configuration that will compare
	 * @return int lower or higher
	 */
	@Override
	public int compareTo(Configuration conf) {		
		int thisPosition = ((AbstractConstraint) this.getConstraint()).getFsaPosition(this.getFsa());
		int objPosition = ((AbstractConstraint) conf.getConstraint()).getFsaPosition(conf.getFsa());
				
		return thisPosition > objPosition ? + 1 : (thisPosition > objPosition ? -1 : 0); 
	}
	
	public abstract String toString();
}